home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / quarkpy / mapentities.py < prev    next >
Text File  |  2004-01-05  |  24KB  |  701 lines

  1. """   QuArK  -  Quake Army Knife
  2.  
  3. Map Editor Entities manager
  4. """
  5. #
  6. # Copyright (C) 1996-99 Armin Rigo
  7. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  8. # FOUND IN FILE "COPYING.TXT"
  9. #
  10.  
  11. #$Header: /cvsroot/quark/runtime/quarkpy/mapentities.py,v 1.30 2003/03/23 07:31:18 tiglari Exp $
  12.  
  13.  
  14. import quarkx
  15. from maputils import *
  16. import maphandles
  17. import mapoptions
  18.  
  19. #
  20. # Classes that implement operations on all types of Map Objects,
  21. # e.g. Quake entities, groups, brush entities, duplicators, etc.
  22. # See the base class, EntityManager, for more information about
  23. # the available methods.
  24. #
  25. # Note: there is a special trick with these classes.
  26. # They are not supposed to be used to build instances from;
  27. # instead, they are merely a convenient way to pack functions.
  28. # These functions are NOT called with a first argument "self"
  29. # which is an instance of the class. They are extracted from
  30. # the class and called directly. The first argument is always
  31. # the QuArK object that the operation applies to.
  32. #
  33. # Call them with CallManager().
  34. #
  35.  
  36. def ObjectOrigin(o):
  37.     "Returns the origin of the map object o, or the center of its bounding box."
  38.     pos = o.origin
  39.     if pos is None:
  40.         #
  41.         # The object has no "origin", let's compute its bounding box.
  42.         #
  43.         box = quarkx.boundingboxof([o])
  44.         if box is None:
  45.             return None
  46.         pos = 0.5*(box[0]+box[1])
  47.     return pos
  48.  
  49. #
  50. # Entity Manager base class, followed by subclasses.
  51. #
  52.  
  53. class EntityManager:
  54.     "Base class for entity managers."
  55.  
  56.     #
  57.     # All methods below are here to be overridden in subclasses.
  58.     #
  59.  
  60.     def drawback(o, editor, view, mode):
  61.         "Called to draw a background for the object 'o'."
  62.         view.drawmap(o, mode)  # draw a dark background for "o"
  63.  
  64.     def drawsel(o, view, mode):
  65.         "Called to draw the object 'o' selected."
  66.         view.drawmap(o, mode)  # draw normally by default
  67.  
  68.     def handles(o, editor, view):
  69.         "Build a list of handles related to this object."
  70.         pos = ObjectOrigin(o)
  71.         if pos is None:
  72.             return []
  73.         return [maphandles.CenterHandle(pos, o, MapColor("Tag"))]
  74.  
  75.     def applylinear(entity, matrix):
  76.         "Apply a linear mapping on this object."
  77.         pass
  78.  
  79.     def dataformname(o):
  80.         "The name of the data form to use for the Specific/Args page."
  81.         return "Default" + o.type
  82.  
  83.     def menu(o, editor):
  84.         "A pop-up menu related to the object."
  85.         import mapmenus
  86.         return CallManager("menubegin", o, editor) + mapmenus.BaseMenu([o], editor)
  87.  
  88.     def menubegin(o, editor):
  89.         return []
  90.  
  91.  
  92. #
  93. # A function to determine which Specifics in a Quake entity
  94. # are to be considered as 2D or 3D angles.
  95. #
  96.  
  97. def ListAngleSpecs(entity):
  98.     h2D = maphandles.Angle2DHandle
  99.     h3D = maphandles.Angles3DHandle
  100.     if entity["light"] and entity["target"]:
  101.         h = []    # ignore "angle" in light entities
  102.     else:
  103.         h = [("angle", h2D)]    # "angle" is 2D
  104.     h.append(("angles", h3D))   # "angles" is 3D
  105.     h.append(("mangle", h3D))   # "mangle" is 3D
  106.     return h
  107.  
  108. def entitylinear(entity, matrix):
  109.     #
  110.     # If we rotate the entity, its angle Specifics must be updated.
  111.     #
  112.     for spec, cls in ListAngleSpecs(entity):
  113.         s = entity[spec]
  114.         if s:
  115.             stov, vtos = cls.map
  116.             try:
  117.                 normal = stov(s)
  118.             except:
  119.                 continue
  120.             normal = matrix * normal
  121.             entity[spec] = vtos(normal)
  122.             return
  123.  
  124.  
  125.  
  126. class EntityType(EntityManager):
  127.     "Quake non-brush Entities"
  128.  
  129.     def handles(o, editor, view):
  130.         return maphandles.CenterEntityHandle(o, view)
  131.  
  132.     applylinear = entitylinear
  133.  
  134.     def drawback(o, editor, view, mode):
  135.         view.drawmap(o, mode)  # draw a dark background for "o"
  136.         drawentitylines(editor, [o], view)
  137.  
  138.     def dataformname(o):
  139.         return o.shortname
  140.  
  141.     def menubegin(o, editor):
  142.         import mapmenus
  143.         return mapmenus.EntityMenuPart([o], editor)
  144.  
  145.  
  146.  
  147. class DuplicatorType(EntityType):
  148.     "Duplicators"
  149.  
  150.     def applylinear(entity, matrix):
  151.         try:
  152.             import mapduplicator
  153.             mapduplicator.DupManager(entity).applylinear(matrix)
  154.         except:
  155.             pass
  156.  
  157.     def dataformname(o):
  158.         import mapduplicator
  159.         return mapduplicator.DupManager(o).dataformname()
  160.  
  161.     def handles(o, editor, view):
  162.         import mapduplicator
  163.         return mapduplicator.DupManager(o).handles(editor, view)
  164.  
  165.  
  166. class GroupType(EntityManager):
  167.     "QuArK groups"
  168.  
  169.     def handles(o, editor, view):
  170.         pos = ObjectOrigin(o)
  171.         if pos is None:
  172.             return []
  173.         h = [maphandles.CenterHandle(pos, o, MapColor("Tag"))]
  174.         if o["usercenter"] is not None:
  175.             h.append(maphandles.UserCenterHandle(o))
  176.         return h
  177.  
  178.     def drawsel(o, view, mode):
  179.         # draw group selected
  180.         view.drawmap(o, mode | DM_SELECTED, view.setup.getint("SelGroupColor"))
  181.  
  182.     def menu(o, editor):
  183.  
  184.         def subspecs(m, group=o, editor=editor):
  185.             editor.layout.explorer.sellist = group.subitems
  186.             editor.layout.mpp.viewpage(1)
  187.  
  188.         import mapbtns
  189.         Spec1 = qmenu.item("Common &specifics...", subspecs, "Specifics/Args of sub-items")
  190.         Spec1.state = qmenu.default
  191.         edit1 = qmenu.popup("Edit", EntityManager.menu.im_func(o, editor), hint="general editing functions")
  192.         usercenter1 = qmenu.item("Add user center", qmacro.MACRO_usercenter, "User controlled pivot point for the group")
  193.         usercenter1.state = (o["usercenter"] is not None) and qmenu.disabled
  194.         GroupCol1 = qmenu.item("Group &color...", mapbtns.groupcolor, "the color to draw the group")
  195.         GroupCol1.rev = 0
  196.         RevertCol1 = qmenu.item("Back to &default color", mapbtns.groupcolor, "removes the special color")
  197.         RevertCol1.rev = 1
  198.         RevertCol1.state = not o["_color"] and qmenu.disabled
  199.         import mapmenus
  200.         return [Spec1, edit1, usercenter1, qmenu.sep, GroupCol1, RevertCol1, qmenu.sep] + mapmenus.ViewGroupMenu(editor)
  201.  
  202.     def menubegin(o, editor):
  203.         import mapmenus
  204.         import mapbtns
  205.         Spec1 = qmenu.item("&Specifics of the group...", mapmenus.set_mpp_page, "Specifics/Args for the group")
  206.         Spec1.page = 1
  207.         Tex1 = qmenu.item("&Texture...", mapbtns.texturebrowser, "choose texture of all sub-items")
  208.         return [Spec1, Tex1, qmenu.sep]
  209.  
  210.  
  211.  
  212. class BrushEntityType(EntityManager):
  213.     "Quake Brush Entities"
  214.  
  215.     def drawsel(o, view, mode):
  216.         # draw group selected
  217.         view.drawmap(o, mode | DM_SELECTED, view.setup.getint("SelGroupColor"))
  218.  
  219.     def drawback(o, editor, view, mode):
  220.         view.drawmap(o, mode)  # draw a dark background for "o"
  221.         drawentitylines(editor, [o], view)
  222.  
  223.     applylinear = entitylinear
  224.  
  225.     def handles(o, editor, view):
  226.         return maphandles.CenterEntityHandle(o, view, pos=ObjectOrigin(o))
  227.  
  228.     def dataformname(o):
  229.         return o.shortname
  230.  
  231.     def menubegin(o, editor):
  232.         import mapmenus
  233.         return mapmenus.EntityMenuPart([o], editor)
  234.  
  235.  
  236.  
  237. def PolyHandles(o, exclude):
  238.     "Makes a list of polyhedron handles, excluding the face 'exclude'."
  239.     h = []
  240.     pos = o.origin
  241.     if not (pos is None):
  242.         #
  243.         # Vertex handles.
  244.         #
  245.         for v in o.vertices:
  246.             h.append(maphandles.VertexHandle(v, o))
  247.         #
  248.         # Face handles.
  249.         #
  250.         for f in o.faces:
  251.             if f!=exclude:
  252.                 #
  253.                 # Compute the center of the face.
  254.                 #
  255.                 vtx = f.verticesof(o)
  256.                 center = reduce(lambda x,y: x+y, vtx)/len(vtx)
  257.                 #
  258.                 # Create the handle at this point.
  259.                 #
  260.                 h.append(maphandles.PFaceHandle(center, f))
  261.         #
  262.         # Finally, add the polyhedron center handle.
  263.         #
  264.         h.append(maphandles.PolyHandle(pos, o))
  265.  
  266.     return h
  267.  
  268.  
  269.  
  270. class PolyhedronType(EntityManager):
  271.     "Polyhedrons"
  272.  
  273.     def handles(o, editor, view):
  274.         h = PolyHandles(o, None)
  275.         if h:
  276.             return h
  277.         #
  278.         # No handle... Maybe the inherited method has some handles to provide.
  279.         #
  280.         return EntityManager.handles.im_func(o, editor, view)
  281.  
  282.     def menubegin(o, editor):
  283.         import mapmenus
  284.         import mapbtns
  285.         h = [ ]
  286.         if editor.layout.mpp.n != 2:
  287.             Spec1 = qmenu.item("&Polyhedron page...", mapmenus.set_mpp_page, "display polyhedron information")
  288.             Spec1.page = 2
  289.             Spec1.state = qmenu.default
  290.             h.append(Spec1)
  291.         Tex1 = qmenu.item("&Texture...", mapbtns.texturebrowser, "choose texture of polyhedron")
  292.         return h + [Tex1] + mapmenus.MenuTexFlags(editor) + [qmenu.sep]
  293.  
  294.  
  295.  
  296. class FaceType(EntityManager):
  297.     "Polyhedron Faces"
  298.  
  299.     def drawback(o, editor, view, mode):
  300.         #
  301.         # To draw the background of a face, we actually draw the whole polyhedron.
  302.         #
  303.         for src in o.faceof:
  304.             view.drawmap(src, mode)
  305.  
  306.     def drawsel(o, view, mode):
  307.         view.drawmap(o, mode | DM_SELECTED, view.setup.getint("SelFaceColor"))
  308.  
  309.     def handles(o, editor, view):
  310.         #
  311.         # Face handles
  312.         #
  313.         if view.viewmode in texturedmodes:
  314.             #
  315.             # Cyan L handles are useful on textured views only.
  316.             #
  317.             h = maphandles.BuildCyanLHandles(editor, o)
  318.         else:
  319.             h = []
  320.         #
  321.         # Add handles from the polyhedron(s) that owns this face.
  322.         #
  323.         for p in o.faceof:
  324.             if p.type==":p":
  325.                 h = h + PolyHandles(p, o)
  326.         #
  327.         # Add handles for the face itself - once per polyhedron that owns this face.
  328.         #
  329.         scale = view.scale()
  330.         for vtx in o.vertices:
  331.             #
  332.             # vtx is a list of vertices. (o.vertices was a list of lists)
  333.             # Compute the center of this face.
  334.             #
  335.             center = reduce(lambda x,y: x+y, vtx)/len(vtx)
  336.             #
  337.             # Make a handle at this point.
  338.             #
  339.             h1 = maphandles.FaceHandle(center, o)
  340.             #
  341.             # Make a "normal vector" handle araising from this point.
  342.             #
  343.             h2 = maphandles.FaceNormalHandle(center, vtx, o, scale)
  344.             #
  345.             # Add these new handles to the list.
  346.             #
  347.             h = h + [h2, h1]
  348.         return h
  349.  
  350.     def menu(o, editor):
  351.         import mapmenus
  352.         import mapbtns
  353.         h = [ ]
  354.         if editor.layout.mpp.n != 3:
  355.             Spec1 = qmenu.item("&Face page...", mapmenus.set_mpp_page, "display face information")
  356.             Spec1.page = 3
  357.             Spec1.state = qmenu.default
  358.             h.append(Spec1)
  359.         Tex1 = qmenu.item("&Choose Texture...", mapbtns.texturebrowser, "choose texture for face")
  360.         texpop = qmenu.popup("&Texture",[Tex1]+ mapmenus.MenuTexFlags(editor))
  361.         texpop.label = 'texpop'
  362.         import mapselection
  363.         Cancel1 = qmenu.item("&Cancel Selections", mapselection.EscClick, "cancel all items selected")
  364.         Force1 = qmenu.item("&Force center to grid", editor.ForceEverythingToGrid, "force to grid")
  365.         Force1.state = not editor.gridstep and qmenu.disabled
  366.         return h + [texpop, qmenu.sep, Cancel1, qmenu.sep, Force1]
  367.  
  368.  
  369. #
  370. # Maybe these functions should be shifted to mapbezier,
  371. # with an empty menu set up here, and the functions added
  372. # using the technique employed for project texture from
  373. # tagged in mapbezier
  374. #
  375. class BezierType(EntityManager):
  376.     "Bezier Patches"
  377.  
  378.     # tiglari
  379.     def menubegin(o, editor):
  380.         import mapmenus
  381.         import mapbtns
  382.  
  383.         def swapclick(m, o=o, editor=editor):
  384.             new = o.copy()
  385.             new.swapsides();
  386.             undo=quarkx.action()
  387.             undo.exchange(o, new)
  388.             editor.ok(undo, "Swap Sides")
  389.  
  390.         Tex1 = qmenu.item("Choose &Texture...", mapbtns.texturebrowser, "choose texture for patch")
  391.  
  392.         texpop = qmenu.popup("&Texture",[Tex1])
  393.         texpop.label="texpop"
  394.         swap = qmenu.item("&Swap sides",swapclick,"Flip visible side of patch")
  395.  
  396.         return [texpop, swap]
  397.  
  398.     # /tiglari
  399.  
  400.     def tex_handles(o, editor, view):
  401.         import mapbezier
  402.         #
  403.         # Bezier handles : one per control point
  404.         #
  405.         colors = [[0xF00000, 0xD00000, 0xB00000, 0x900000, 0x700000],   #DECKER
  406.                   [0x00F000, 0x00D000, 0x00B000, 0x009000, 0x007000],
  407.                   [0x0000F0, 0x0000D0, 0x0000B0, 0x000090, 0x000070],
  408.                   [0xF0F000, 0xD0D000, 0xB0B000, 0x909000, 0x707000],
  409.                   [0x00F0F0, 0x00D0D0, 0x00B0B0, 0x009090, 0x007070],
  410.                   [0xF000F0, 0xD000D0, 0xB000B0, 0x900090, 0x700070],
  411.                   [0xF0F0F0, 0xD0D0D0, 0xB0B0B0, 0x909090, 0x707070]]
  412.         coli = 0 #DECKER
  413.         h = []
  414.         cp = o.cp
  415.         for i in range(len(cp)):
  416.             colj = 0 #DECKER
  417.             cpline = cp[i]
  418.             for j in range(len(cpline)):
  419.                 c1 = cpline[j]
  420.                 # makes a list of couples (projected position, handle object)
  421.                 c1 = quarkx.vect(c1.s, c1.t, 0)
  422.                 h.append( mapbezier.CPTextureHandle(c1, o, (i,j), colors[coli][colj])) #DECKER
  423.                 colj = (colj+1)%4
  424.             coli = (coli+1)%6
  425.  
  426.         return h
  427.  
  428.  
  429.     def handles(o, editor, view):
  430.         import mapbezier
  431.         #
  432.         # Bezier handles : one per control point
  433.         #
  434.         colors = [[0xF00000, 0xD00000, 0xB00000, 0x900000, 0x700000],   #DECKER
  435.                   [0x00F000, 0x00D000, 0x00B000, 0x009000, 0x007000],
  436.                   [0x0000F0, 0x0000D0, 0x0000B0, 0x000090, 0x000070],
  437.                   [0xF0F000, 0xD0D000, 0xB0B000, 0x909000, 0x707000],
  438.                   [0x00F0F0, 0x00D0D0, 0x00B0B0, 0x009090, 0x007070],
  439.                   [0xF000F0, 0xD000D0, 0xB000B0, 0x900090, 0x700070],
  440.                   [0xF0F0F0, 0xD0D0D0, 0xB0B0B0, 0x909090, 0x707070]]
  441.         coli = 0 #DECKER
  442.         h = []
  443.         cp = o.cp
  444.         for i in range(len(cp)):
  445.             colj = 0 #DECKER
  446.             cpline = cp[i]
  447.             for j in range(len(cpline)):
  448.                 c1 = cpline[j]
  449.                 # makes a list of couples (projected position, handle object)
  450.                 h.append((view.proj(c1), mapbezier.CPHandle(c1, o, (i,j), colors[coli][colj]))) #DECKER
  451.                 colj = (colj+1)%4
  452.             coli = (coli+1)%6
  453.  
  454.         h.sort()  # sort on Z-order, nearest first
  455.         h.reverse()  # we have to draw back handles first, so reverse the order
  456.         h = map(lambda x: x[1], h)  # extract the 2nd component of all couples (i.e., keep only handle objects)
  457.  
  458.         #
  459.         # Add a center handle
  460.         #
  461.         try:
  462.             # put the handle in the middle of the first square of control points
  463.             pos = 0.25 * (cp[0][0]+cp[0][1]+cp[1][0]+cp[1][1])
  464.         except IndexError:
  465.             # there are not enough control points
  466.             pos = o.origin
  467.         if pos is not None:
  468.             h.append(mapbezier.CenterHandle(pos, o))
  469.  
  470.         return h
  471.  
  472.  
  473. #
  474. # Mappings between Internal Objects types and Entity Manager classes.
  475. #
  476.  
  477. Mapping = {
  478.     ":d": DuplicatorType(),
  479.     ":e": EntityType(),
  480.     ":g": GroupType(),
  481.     ":b": BrushEntityType(),
  482.     ":p": PolyhedronType(),
  483.     ":f": FaceType(),
  484.     ":b2": BezierType() }
  485.  
  486. #
  487. # Use the function below to call a method of the Entity Manager classes.
  488. # Syntax is : CallManager("method", entity, arguments...)
  489. #
  490.  
  491. def CallManager(fn, *args):
  492.     "Calls a function suitable for the QuArK object given as second argument."
  493.     try:
  494.         mgr = Mapping[args[0].type]
  495.     except KeyError:
  496.         mgr = EntityManager()    # unknown type
  497.     return apply(getattr(mgr, fn).im_func, args)  # call the function
  498.  
  499.  
  500.  
  501. #
  502. # To Armin:
  503. #   Change the existing 'def drawentitylines()' in quarkpy/mapentities.py, to all this.
  504. #   Notice that there is a new setting; "EntityLinesDispersion". If its enabled, it can really increase the time QuArK/Windows
  505. #    spends drawing graphics. (And it confuses me a bit, when I only wants to see what connections one entity has got).
  506. #   Notice that here Arrow() now sends an extra argument, a text, so the Arrow() function should be modified to take this, but
  507. #    does not need to do anything with it, yet!
  508.  
  509.  
  510. class DefaultDrawEntityLines:
  511.  
  512.    def drawentityarrow(self, entity, org, backarrow, color, view, processentities, text=None):
  513.         org2 = ObjectOrigin(entity)
  514.         if org2 is not None:
  515.             cv = view.canvas()
  516. #            cv.penwidth = 2 # DECKER - Make this a configurable size
  517.             cv.penwidth = mapoptions.getThinLineThickness()
  518.             cv.pencolor = color
  519. # DECKER - These font settings are commented out at the moment
  520. #           cv.fontname =               # DECKER - Make this configurable
  521. #           cv.fontcolor = color
  522. #           cv.fontsize =               # DECKER - Make this configurable
  523.             if backarrow:
  524.                 Arrow(cv, view, org2, org, text) # DECKER - When the Arrow() function can draw a text with it, we're ready for it
  525.             else:
  526.                 Arrow(cv, view, org, org2, text) # DECKER - When the Arrow() function can draw a text with it, we're ready for it
  527.             if MapOption("EntityLinesDispersion"): # DECKER - Make this switchable for the user!!!
  528.                 if not (entity in processentities):   # remove this to remove
  529.                     processentities.append(entity)    #  recurrence in entity lines
  530.  
  531.    def drawentityarrows(self, spec, arg, org, backarrow, color, view, entities, processentities, text=None):
  532.         for e in tuple(entities):
  533.             if e[spec]==arg:
  534.                 self.drawentityarrow(e, org, backarrow, color, view, processentities, text)
  535.  
  536.    def drawentitylines(self, entity, org, view, entities, processentities):
  537.         color = MapColor("Axis")
  538.         org1 = view.proj(org)
  539.         if org1.visible:
  540.             L1 = entity["light"]
  541.             L2 = entity["_light"]
  542.             if L1 or L2:
  543.                 try:
  544.                     if L1:
  545.                         radius = float(L1)
  546.                         if entity["_color"]:
  547.                             try:
  548.                                 color = quakecolor(quarkx.vect(entity["_color"]))
  549.                             except:
  550.                                 pass
  551.                     else:
  552.                         L2 = readfloats(L2)
  553.                         radius = L2[3]
  554.                         color = makeRGBcolor(L2[0], L2[1], L2[2])
  555.                     lightfactor, = quarkx.setupsubset()["LightFactor"]
  556.                     radius = radius * view.scale(org) * lightfactor
  557.                     cv = view.canvas()
  558.                     cv.pencolor = color
  559. #                    cv.penwidth = 2 # DECKER - Make this a configurable size
  560.                     cv.penwidth = mapoptions.getThinLineThickness()
  561.                     cv.brushstyle = BS_CLEAR
  562.                     cv.ellipse(org1.x-radius, org1.y-radius, org1.x+radius, org1.y+radius)
  563.                 except:
  564.                     pass
  565.         if entity["target"] is not None:
  566.            self.drawentityarrows("targetname", entity["target"], org, 0, color, view, entities, processentities)
  567.         if entity["targetname"] is not None:
  568.            self.drawentityarrows("target", entity["targetname"], org, 1, color, view, entities, processentities)
  569.            self.drawentityarrows("killtarget", entity["targetname"], org, 1, RED, view, entities, processentities)
  570.         if entity["killtarget"] is not None:
  571.            self.drawentityarrows("targetname", entity["killtarget"], org, 0, RED, view, entities, processentities)
  572.  
  573. #
  574. # EntityLines Manager list
  575. #
  576. EntityLinesMapping = {
  577.   "Default": DefaultDrawEntityLines()
  578. }
  579.  
  580. def drawentitylines(editor, processentities, view):
  581.     "According to the choosen game, draw additionnal lines and arrows (e.g. target to targetname)"
  582.     entities = editor.AllEntities()
  583.     try:
  584.         mgr = EntityLinesMapping[quarkx.setupsubset().shortname] # DECKER - Find a drawentitylines-mgr for this game
  585.     except KeyError:
  586.         mgr = EntityLinesMapping["Default"] # DECKER - Hmm? Use the default manager, since there wasn't any plugin for the selected game
  587.     i = 0
  588.     while i<len(processentities):
  589.         entity = processentities[i]
  590.         i=i+1
  591.         if entity in entities:
  592.             entities.remove(entity)
  593.         org = ObjectOrigin(entity)
  594.         if org is None:
  595.             continue
  596.         mgr.drawentitylines(entity, org, view, entities, processentities) # DECKER - Call the manager
  597.  
  598.  
  599. #
  600. # Function to load the form corresponding to an entity list.
  601. #
  602.  
  603. formdict = {}
  604.  
  605. def lookupPyForm(f1):
  606.     if formdict.has_key(f1):
  607.         return formdict[f1]
  608.  
  609. def registerPyForm(name, formstring):
  610.     f = quarkx.newobj(name+":form")
  611.     f.loadtext(formstring)
  612.     formdict[name] = f
  613.  
  614. def LoadEntityForm(sl):
  615.     formobj = None
  616.     if len(sl):
  617.         f1 = CallManager("dataformname", sl[0])
  618.         for obj in sl[1:]:
  619.             f2 = CallManager("dataformname", obj)
  620.             if f2!=f1:
  621.                 f1 = None
  622.                 break
  623.         if f1 is not None:
  624.             #bbox = LoadPoolObj("BoundingBoxes", quarkx.getqctxlist, ":form")
  625.             #for f in bbox:
  626.             #    if f.shortname == f1:
  627.             #        formobj = f        # find the LAST form
  628.             flist = quarkx.getqctxlist(':form', f1)
  629.             if len(flist):
  630.                 formobj = flist[-1]
  631.         if formobj is None:
  632.             formobj = lookupPyForm(f1)
  633.     return formobj
  634.  
  635.  
  636. # ----------- REVISION HISTORY ------------
  637. #$Log: mapentities.py,v $
  638. #Revision 1.30  2003/03/23 07:31:18  tiglari
  639. #make trigger-target line thickness configurable
  640. #
  641. #Revision 1.29  2003/02/13 15:56:53  cdunde
  642. #To add Cancel Selections function to RMB menu.
  643. #
  644. #Revision 1.28  2001/08/16 20:09:29  decker_dk
  645. #Put 'Add user center' menuitem on Treeview Group's context-menu. Its more visible there.
  646. #
  647. #Revision 1.27  2001/04/10 08:52:57  tiglari
  648. #remove CustomObjectOrigin
  649. #
  650. #Revision 1.26  2001/03/31 13:01:35  tiglari
  651. #usercenter for groups (for rotation)
  652. #
  653. #Revision 1.25  2001/03/22 08:14:31  tiglari
  654. #origin duplicator bugfix
  655. #
  656. #Revision 1.24  2001/03/21 21:19:08  tiglari
  657. #custom origin (center for groups) duplicator support
  658. #
  659. #Revision 1.23  2001/02/07 18:40:47  aiv
  660. #bezier texture vertice page started.
  661. #
  662. #Revision 1.22  2001/01/10 20:25:53  tiglari
  663. #fix bug in registerPyForm
  664. #
  665. #Revision 1.21  2000/12/31 02:46:02  tiglari
  666. #Support for python code to add entity forms
  667. # (for shape-generator development: lookup/registerPyForm)
  668. #
  669. #Revision 1.20  2000/07/29 02:06:35  tiglari
  670. #my idea of how to do `hardcore' color coding
  671. #
  672. #Revision 1.19  2000/07/26 11:34:02  tiglari
  673. #changes for bezier menu reorganizations
  674. #
  675. #Revision 1.18  2000/07/24 12:48:39  tiglari
  676. #reorganization of bezier texture menu
  677. #
  678. #Revision 1.17  2000/07/24 09:09:23  tiglari
  679. #Put Texture.. (choose) and Texture Flags into a submenu labelled 'texpop', for texture menu cleanup as suggested by Brian Audette
  680. #
  681. #Revision 1.16  2000/07/16 07:56:26  tiglari
  682. #bezier menu -> menubegin
  683. #
  684. #Revision 1.15  2000/06/04 03:22:28  tiglari
  685. #texture choice item for b2 menu
  686. #
  687. #Revision 1.14  2000/06/02 16:00:22  alexander
  688. #added cvs headers
  689. #
  690. #Revision 1.13  2000/05/26 23:07:39  tiglari
  691. #fiddled with beziertype entity manager
  692. #
  693. #Revision 1.12  2000/05/19 10:13:39  tiglari
  694. #fixed `snap' in revision history at bottom
  695. #
  696. #Revision 1.11  2000/05/19 10:11:13  tiglari
  697. #added revision history, comments on use of BezierType menu
  698. #
  699. #
  700.  
  701.